<!doctype html>
<html lang="en">

<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>Hello, world!</title>
    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="../css/font-awesome.min.css">
    <link rel="stylesheet" href="../css/bootstrap.min.css">
    <link rel="stylesheet" href="../css/bootstrap-select.min.css">
    <link rel="stylesheet" href="../css/select2.min.css">
    <link rel="stylesheet" href="../css/select2-bootstrap4.min.css">

    <link rel="stylesheet" href="../css/style.css">
    <style>
        .bd-placeholder-img {
            font-size: 1.125rem;
            text-anchor: middle;
            -webkit-user-select: none;
            -moz-user-select: none;
            -ms-user-select: none;
            user-select: none;
        }

        @media (min-width: 768px) {
            .bd-placeholder-img-lg {
                font-size: 3.5rem;
            }
        }

        html,
        body {
            height: 100%;
        }

        body {
            padding-bottom: 40px;
            background-color: #fff;
        }

        .form-signin {
            width: 100%;
            max-width: 640px;
            margin: auto;
            padding: 15px;
        }

        .form-signin .checkbox {
            font-weight: 400;
        }

        .form-signin .form-control {
            position: relative;
            box-sizing: border-box;
            height: auto;
            padding: 10px;
            font-size: 16px;
        }

        .form-signin .form-control:focus {
            z-index: 2;
        }

        .form-signin input[type="email"] {
            margin-bottom: -1px;
            border-bottom-right-radius: 0;
            border-bottom-left-radius: 0;
        }

        .form-signin input[type="password"] {
            margin-bottom: 10px;
            border-top-left-radius: 0;
            border-top-right-radius: 0;
        }

        .sr-only2 {
            margin-top: 15px;
        }


        .logodiv img {
            width: 240px;
            margin: 0 auto;
            display: block;
        }

        .logodiv {
            text-align: center;
        }

        .logodiv h1 {
            font-size: 1.4rem;
            color: #03357a;
            margin-top: 20px;
            margin-bottom: 20px;
        }

        .logodiv h2 {
            font-size: 1.5rem;
            margin-bottom: 80px;
        }



        .fgtpaws {
            text-align: center;
            margin-top: 10px;
        }

        .btn {
            padding: 0.375rem 0.15rem
        }

        .btn-tiqu {
            width: 125px;
            margin: 0 auto;
            display: block;
        }

        .buytitle {
            font-size: 1.1rem;
            color: #03357a;
            margin-top: 20px;
        }

        .buytitle span {
            font-size: 1rem;
            color: #999;
        }
        .action-row button {
            margin-bottom: 15px;
        }

        .buysearch {
            font-size: smaller;
        }
        .formscreen .form-control-theme {
            font-size: smaller;
        }

        .action-row {
            position: fixed;
            width: 100%;
            bottom: 0;
            margin-top: 0;
            margin-bottom: 0;
            background: #fff;
            left: 0;
        }

        .container2 {
            padding: 10px;
            display: block;
            overflow: hidden;
        }

        .bootstrap-select {
            width: calc(100% - 0px) !important;
        }

        .formscreen .filter-option-inner-inner {
            font-size: smaller;
        }

        .myselect {
            width: calc(100% - 0px);
        }

        .btn-action:disabled {
            background: #D9D9DA !important;
            color: #808081 !important;
        }

        .buysearch {
            width: 100%;
            display: block;
        }
    </style>
</head>

<body>
    <div id="app">
        <div class="container2">





            <div class="tab-pane  show active" id="home">
                <h2 class="buytitle"><span>({{lan['Generate_SN']}})</span></h2>

                <div v-if="list.length>0" class="row  align-items-center">
                    <div id="shouitem" class="col-12 col-sm-6 col-md-4">
                        <div class="d-flex bd-highlight align-items-start">

                            <div class="pt-2 flex-grow-1 bd-highlight">
                                <table class="table table-buy table-borderless table-sm">

                                    <tr>
                                        <td class="ttl" colspan="2">{{lan['Part']}}/{{lan['Desc']}}</td>
                                        <td class="ttl">{{lan['Transaction_Qty']}}</td>
                                    </tr>
                                    
                                    <tr>
                                        <td>{{searchdata.PartNum}}<br>{{searchdata.PartDescription}}</td>
                                        <td>{{searchdata.OnhandQty}}</td>
                                    </tr>
                                   
                                </table>
                            </div>
                        </div>
                    </div>

                </div>
            </div>



            <table v-if="searchdata.SerialNum.length > 0" class="table table-buy table-borderless table-sm">
                <tr>
                    <td width="50" class="ttl"></td>
                    <td v-if="SNPrefix!=''" width="50" class="ttl">{{lan['Prefix']}}</td>
                    <td class="ttl">{{lan['Please_enter_Serial_No']}}</td>
                </tr>
                <tr style="vertical-align: middle;" v-for="(item,index) in searchdata.SerialNum"
                 :key="'shou'+item.SerialNumber">
                    <td style="vertical-align: middle;text-align: center;">{{index+1}}</td>
                    <td v-if="SNPrefix!=''"><div  class="d-flex">
                        <input type="text"
                            disabled
                            v-model="SNPrefix"
                            class="form-control form-control-num" value="">
                    </div></td>
                    <td>
                        <div class="d-flex">
                            <input type="text"
                                :disabled='searchdata.Lot_btn || searchdata.createCheck'
                                @change="serialChange(item,index)"
                                @blur="validateSerialNumber(item,index)"
                                v-model.lazy="searchdata['SerialNum'][index].SerialNumber"
                                class="form-control form-control-num" value="">
                        </div>
                    </td>
                </tr>
                
            </table>

        </div>

        <div style="height:100px;"></div>
        <div class="action-row">
            <div class="container">
                <div class=" row justify-content-center">
                    <div class="col-4 col-md-4">
                        <button type="button" tapmode=""  @click="comfirmClick"
                            class="btn btn-primary btn-action">{{lan['Comfirm']}}</button>
                    </div>

                    <div class="col-4 col-md-4">
                       
                    </div>


                    <div class="col-4 col-md-4">
                        <button type="button" tapmode="" @click="close();"
                            class="btn btn-primary btn-action">{{lan['Cancel']}}
                        </button>
                    </div>

                </div>

            </div>

        </div>
    </div>

</body>
<script type="text/javascript" src="../script/lang.js"></script>
<script type="text/javascript" src="../script/model.js"></script>
<script type="text/javascript" src="../script/api.js"></script>
<script type="text/javascript" src="../script/vue.min.js"></script>
<script type="text/javascript" src="../script/jquery.min.js"></script>
<script type="text/javascript" src="../script/bootstrap.bundle.min.js"></script>
<script type="text/javascript" src="../script/bootstrap-select.min.js"></script>
<script type="text/javascript" src="../script/select2/select2.min.js"></script>
<script type="text/javascript" src="../script/common.js"></script>
<script type="text/javascript">
    var postcount = 0;
    var tagspostcount = 0;
    var returncount = 0;
    var postlist = [];
    var tags = [];

    const app = new Vue({
        el: '#app',
        data: {
            list: [],
            item: {},
            screenwidth: document.body.clientWidth,
            vendors: [],
            searchdata: {
                SerialNum:[],
            },
            uinfo: {},
            lotinfo: {},
            create_btn: false,
            receipt_btn: false,
            print_btn: true,
            confirm_btn:true,
            print_num: '',
            entryCheck:false,
            SNFormat:"",
            SNBaseDataType:"",
            MaskType:"",
            SNPrefix:"",
            PackSlip:"",
            PackLine:"",
            ImportNum:"",
        },
        mounted() {
            const that = this
        },
        methods: {
            serialChange(item,index){
                app.searchdata.SerialNum[index].RawSerialNum =this.SNPrefix + item.SerialNumber;
                app.searchdata.SerialNum[index].SNBaseNumber =this.SNPrefix + item.SerialNumber;
                
            },
            // 添加一个新的方法用于更新 LabelNum 和 CartonNum
            updateLabelAndCarton: function () {
                var posts = app.searchdata.SerialNum;
                for (i in posts) {
                    if (this.xz_index == posts[i].xs) {
                        this.LabelNum = posts[i].LabelNum;
                        this.CartonNum = posts[i].OnhandQty;
                        break; // 找到匹配的 xs 后可以退出循环
                    }
                }
            },
            comfirmClick() {
                if (this.searchdata.Lot_btn ) {
                    api.closeWin({});
                    return;
                }
                if(this.searchdata.createCheck){
                    api.sendEvent({
                        name: 'sn_qty_update',
                        extra: app.searchdata
                    });
                    api.closeWin({}); 
                }
                let allValid = true; // 标记所有输入是否都通过校验
                app.searchdata.oldQty = app.searchdata.OnhandQty
                for (var i = 0; i < app.searchdata.SerialNum.length; i++) {
                    if (app.searchdata.SerialNum[i].SerialNumber === "") {
                        api.toast({
                            msg: app.searchdata.SerialNum[i].LabelNum + lan['Serialnum_Label_placeholder'],
                            location: 'middle'
                        });
                        return;
                    }
                    const isValid = validateSerialNumber(app.searchdata.SerialNum[i], i);
                    
                    if (!isValid) {
                        allValid = false; // 有一个校验不通过就将标记设为 false
                    }
                }

                if (allValid) {
                    if(app.searchdata.OnhandQty > 0){
                        createSn();
                    }else{
                        closeSnWin();
                    }
                   
                }
                
            },


           close(){
                let allSerialNumbersHaveValue = app.searchdata.SerialNum.every(item => item.SerialNumber);

                if (allSerialNumbersHaveValue) {
                    // 所有SerialNumber都有值，触发直接关闭事件
                    api.closeWin({}); 
                } else {
                    this.$set(app.searchdata,"SerialNum",[])
                    api.sendEvent({
                        name: 'sn_qty_update',
                        extra: app.searchdata
                    });
                    api.closeWin({}); 
                }
                
            }

        }
    });
    apiready = function () {
        api.parseTapmode();
        server = getapi();

        api.addEventListener({ name: 'navitembtn' }, function (ret, err) {
            if (ret.type == 'left') { app.close(); }
            if (ret.type == 'right') { scan(); }
        });
       
        app.searchdata = api.pageParam.searchdata;
        app.entryCheck = api.pageParam.entryCheck;
        app.SNFormat = api.pageParam.SNFormat;
        app.SNBaseDataType = api.pageParam.SNBaseDataType;
        app.MaskType = api.pageParam.MaskType;
        app.SNPrefix = api.pageParam.SNPrefix;
        app.receipt_btn = api.pageParam.receipt_btn;
        app.PackSlip=api.pageParam.PackSlip;
        app.PackLine=api.pageParam.PackLine;
        app.ImportNum=api.pageParam.ImportNum;
        console.log(JSON.stringify(app.searchdata),88888)
        console.log(JSON.stringify(api.pageParam),333333)
        console.log(JSON.stringify(app.searchdata.SerialNum),111111)
        app.uinfo = get_user_info();
        userinfo = get_user_info();
        api.addEventListener({
            name: 'keyback',
            extra: {
                slidBackIntercept: true    
            }
        }, function (ret, err) {
            app.close()
        });
        if(app.SNPrefix != ""){
            let SerialNum = app.searchdata.SerialNum
            SerialNum = SerialNum.map((item) => {
            if (
                typeof item.SerialNumber === "string" &&
                item.SerialNumber.startsWith(app.SNPrefix)
            ) {
                item.SerialNumber = item.SerialNumber.slice(1);
            }
            return item;
            });

            app.searchdata.SerialNum = SerialNum
        }
        app.searchdata.name = userinfo.Name;
        api.addEventListener({
            name: 'infrared_scanning'
        }, function (ret, err) {
            if (ret && ret.value && ret.value.str) {
                if(app.searchdata.OnhandQty > 0){
                    get_code_data(ret.value.str);
                }else{
                    get_code_data1(ret.value.str);
                }
                
            }


        });



    }
    function scan() {
        var FNScanner = api.require('FNScanner');
        FNScanner.open({
            autorotation: true
        }, function (ret, err) {
            console_debug(ret, err);
            if (ret) {
                if (ret.eventType == 'success') {
                    if(app.searchdata.OnhandQty > 0){
                        get_code_data(ret.value.str);
                    }else{
                        get_code_data1(ret.value.str);
                    }
                }

            } else {

            }
        });
    }
    let scannedSerialNumber = [];
    function get_code_data1(content) {
        // 获取扫描到的序列号值
        const scannedValue = content.trim();
        userinfo = get_user_info();
        var filter = "?CompID=" + userinfo.Company;
        filter += "&PartNum=" + app.searchdata.PartNum
        filter += "&WarehouseCode=" + app.searchdata.WarehouseCode;
        filter += "&BinNum=" + app.searchdata.BinNum;
        if(app.searchdata.LotNum){
            filter += "&LotNum=" + app.searchdata.LotNum; 
        }
        filter += "&SerialNum=" + scannedValue
      
        console_debug(filter, '');

        api.ajax({
            url: server + 'BaqSvc/WMS_StockSN/' + filter,
            method: 'get',
            returnAll: false,
            headers: {
                'Authorization': userinfo.Token,
            },
            data: {}
        }, function (ret, err) {
            ajaxing = 0;
            //alert(1);
            console_debug(ret, "loadSerialNum");
            hideProgress();
            if (ret && ret.value.length > 0) {
                // 判断扫描到的序列号是否已经存在于已扫描序列号列表中
                if (scannedSerialNumber.includes(scannedValue)) {
                    api.toast({
                        msg: scannedValue + lan['SerialNum_Unique'],
                        location: 'middle'
                    })
                    return;
                }
              
                let emptyIndex = -1;
                for (let i = 0; i < app.searchdata.SerialNum.length; i++) {
                    if (app.searchdata.SerialNum[i].SerialNumber === '') {
                        emptyIndex = i;
                        break;
                    }
                }

                // 如果找到了空的 SerialNumber，则赋值为扫描到的序列号
                if (emptyIndex >= 0) {
                    app.searchdata.SerialNum[emptyIndex].SerialNumber = scannedValue;
                    scannedSerialNumber.push(scannedValue);
                } else {
                    // 如果没有找到空的 SerialNumber，则遍历除第一个对象之外的其他对象，判断是否存在相同的序列号
                    for (let i = 1; i < app.searchdata.SerialNum.length; i++) {
                        if (app.searchdata.SerialNum[i].SerialNumber === scannedValue) {
                            api.toast({
                                msg: scannedValue + lan['SerialNum_Unique'],
                                location: 'middle'
                            })
                            return;
                        }
                    }
                    // 如果没有相同的序列号，则将其赋值给第一个空的 SerialNumber
                    app.searchdata.SerialNum[emptyIndex].SerialNumber = scannedValue;
                    scannedSerialNumber.push(scannedValue);
                }

            }else{
                 // 序列号无效，显示相应的提示  
                api.toast({  
                    msg: scannedValue + lan['serial_exist_placeholder'],  
                    location: 'middle'  
                });  
            }

        });
        
    }

    function get_code_data(content) {
        const SNFormat = app.SNFormat;
        if(app.SNBaseDataType == "INTEGER"){
            const regex = new RegExp(`^\\d{${SNFormat.length}}$`); // 去掉了 SNPrefix
            if (!regex.test(content)) {
                api.toast({
                    msg: content + lan['SerialNum_placeholder_RuleN'] +"("+ SNFormat.length + ")" +lan['Digits'],
                    location: 'middle'
                })
                return;
            }
        }else if(app.SNBaseDataType == "MASK"){
            let regexPattern = "";

            // 根据 SNFormat 构建正则表达式模式
            // # 表示数字，& 表示字母（只能是数字或字母）
            regexPattern = SNFormat.replace(/#/g, "\\d").replace(/&/g, "[A-Za-z0-9]");

            const regex = new RegExp(`^${regexPattern}$`);
            const errorMsg = lan['SerialNum_placeholder_Rule'] + ` (${SNFormat})`;

            if (!regex.test(content)) {
                api.toast({
                    msg: content + errorMsg,
                    location: 'middle'
                });
                return;
            }

        }else{
             
            // 检查输入长度是否超过40个字符
            if (content.length > 40) {
                api.toast({
                    msg: lan['SerialNum_placeholder_Rule'] + ' (最多40个字符)',
                    location: 'middle'
                });
                return;
            }
            
            // 使用正则表达式验证输入是否包含字母、数字和符号
            const regex = /^[A-Za-z0-9\s!"#$%&'()*+,-./:;<=>?@[\\\]^_`{|}~]*$/;
            if (!regex.test(content)) {
                api.toast({
                    msg: lan['SerialNum_placeholder_Rule'] + ' (包含非法字符)',
                    location: 'middle'
                });
                return;
            }

        }
        
        // 获取扫描到的序列号值
        const scannedValue = content.trim();

        // 判断扫描到的序列号是否已经存在于已扫描序列号列表中
        if (scannedSerialNumber.includes(scannedValue)) {
            api.toast({
                msg: scannedValue + lan['SerialNum_Unique'],
                location: 'middle'
            })
            return;
        }

        // 遍历 SerialNum 列表，查找第一个空的 SerialNumber
        let emptyIndex = -1;
        for (let i = 0; i < app.searchdata.SerialNum.length; i++) {
            if (app.searchdata.SerialNum[i].SerialNumber === '') {
                emptyIndex = i;
                break;
            }
        }

        // 如果找到了空的 SerialNumber，则赋值为扫描到的序列号
        if (emptyIndex >= 0) {
            app.searchdata.SerialNum[emptyIndex].SerialNumber = scannedValue;
            scannedSerialNumber.push(scannedValue);
        } else {
            // 如果没有找到空的 SerialNumber，则遍历除第一个对象之外的其他对象，判断是否存在相同的序列号
            for (let i = 1; i < app.searchdata.SerialNum.length; i++) {
                if (app.searchdata.SerialNum[i].SerialNumber === scannedValue) {
                    api.toast({
                        msg: scannedValue + lan['SerialNum_Unique'],
                        location: 'middle'
                    })
                    return;
                }
            }

            // 如果没有相同的序列号，则将其赋值给第一个空的 SerialNumber
            app.searchdata.SerialNum[emptyIndex].SerialNumber = scannedValue;
            scannedSerialNumber.push(scannedValue);
        }
    }
    function checkSn(value,index){
        userinfo = get_user_info();
        var filter = "?CompID=" + userinfo.Company;
        filter += "&PartNum=" + app.searchdata.PartNum
        filter += "&WarehouseCode=" + app.searchdata.WarehouseCode;
        filter += "&BinNum=" + app.searchdata.BinNum;
        if(app.searchdata.LotNum){
            filter += "&LotNum=" + app.searchdata.LotNum; 
        }
        filter += "&SNStutas='Inventory'"
        filter += "&SerialNum="+value
      
        console_debug(filter, '');

        api.ajax({
            url: server + 'BaqSvc/WMS_StockSN/' + filter,
            method: 'get',
            returnAll: false,
            headers: {
                'Authorization': userinfo.Token,
            },
            data: {}
        }, function (ret, err) {
            ajaxing = 0;
            //alert(1);
            console_debug(ret, "loadSerialNum");
            hideProgress();
            if (ret && ret.value.length > 0) {
           

            }else{
                 // 序列号无效，显示相应的提示  
                api.toast({  
                    msg: value +  lan['serial_exist_placeholder'],  
                    location: 'middle'  
                });
                app.searchdata.SerialNum[index].SerialNumber = '';    
            }

        });
    }
    function createSn(){
        let userinfo = get_user_info();
        let postlist=[];
        var totalOurQty = 0;
        for(let i=0;i<app.searchdata.SerialNum.length;i++){
            postlist.push({
                SNumber:app.searchdata.SerialNum[i].SerialNumber
            })
        }
        console.log(JSON.stringify(app.searchdata.SerialNum),111111)
        console.log(JSON.stringify(postlist),222222)
        let data1={
            "CompanyID": userinfo.Company,
            "PlantID": userinfo.Site,
            "UserName": userinfo.Name,
            "Password": userinfo.password,
            "TranDate":app.searchdata.ArrivedDate,
            "TranQty":app.searchdata.OnhandQty,
            "PartNum":app.searchdata.PartNum,
            "CreateSNs":postlist,
        }
        api.ajax({
            url: wmsserver + 'sninvqtyadj/',
            method: 'post',
            returnAll: false,
            headers: {
                'token': wmstoken,
                'Content-Type': 'application/json;charset=utf-8'
            },
            //dataType: 'text',
            data: {
                body: create_submit_data(data1)
            }
            //data: {values: data1}
        }, function (ret, err) {
            ajaxing = 0;
            console.log(JSON.stringify(ret),4444)
            hideProgress();
            if (ret && ret.code == 1) {
                var snno =[]
                snno = ret.data.SelectedSerialNumbers;
                app.$set(app.$data.searchdata, 'snsCheck', true);
                app.$set(app.$data.searchdata, 'SerialNum', snno);
                app.$set(app.$data.searchdata,'data',ret.data);
                closeSnWin()
            } else {
                app.isclose = true
                hideProgress();
                errMassage(ret.msg)
            }
        });
    }
   
    function validateSerialNumber(item, index) {
        const input = event.target;
        const value = app.searchdata['SerialNum'][index].SerialNumber;
        if(app.searchdata.OnhandQty < 0){
            checkSn(value,index)
        }
        const SNFormat = app.SNFormat;
        if(SNFormat){

        }
        if(app.SNBaseDataType == "INTEGER"){
            const regex = new RegExp(`^\\d{${SNFormat.length}}$`); // 去掉了 SNPrefix
            if (!regex.test(value)) {
                api.toast({
                    msg: value + lan['SerialNum_placeholder_RuleN'] +` (${SNFormat.length})`+lan['Digits'] ,
                    location: 'middle'
                })
                return false;
            }
        }else if(app.SNBaseDataType == "MASK"){
            let regexPattern = "";
            // 根据 SNFormat 构建正则表达式模式
            // # 表示数字，& 表示字母（只能是数字或字母）
            regexPattern = SNFormat.replace(/#/g, "\\d").replace(/&/g, "[A-Za-z0-9]");

            const regex = new RegExp(`^${regexPattern}$`);
            const errorMsg = lan['SerialNum_placeholder_Rule'] + ` (${SNFormat})`;

            if (!regex.test(value)) {
                api.toast({
                    msg: value + errorMsg,
                    location: 'middle'
                });
              
                return false;
            }
        }else{
            // 检查输入长度是否超过40个字符
            if (value.length > 40) {
                api.toast({
                    msg: lan['SerialNum_placeholder_Rule'] + ' (最多40个字符)',
                    location: 'middle'
                });
                return;
            }
            
            // 使用正则表达式验证输入是否包含字母、数字和符号
            const regex = /^[A-Za-z0-9\s!"#$%&'()*+,-./:;<=>?@[\\\]^_`{|}~]*$/;
            if (!regex.test(value)) {
                api.toast({
                    msg: lan['SerialNum_placeholder_Rule'] + ' (包含非法字符)',
                    location: 'middle'
                });
                return false;
            }


        }

        const isDuplicate = app.searchdata.SerialNum.some((serialObj, i) => {
            return i !== index && serialObj.SerialNumber === value;
        });

        if (isDuplicate) {
           
            api.toast({
                msg: value + lan['SerialNum_Unique'],
                location: 'middle'
            });
            return false;
        }

        return true
       
    }



    function closeSnWin() {
        if(app.SNPrefix != ""){
            let SerialNum = app.searchdata.SerialNum
            SerialNum = SerialNum.map((item) => {
            if (typeof item.SerialNumber === "string") {
                item.SerialNumber =app.SNPrefix + item.SerialNumber
            }
            return item;
            });
            console.log(JSON.stringify(SerialNum),8888)
            app.searchdata.SerialNum = SerialNum
        }
        api.sendEvent({
            name: 'sn_qty_update',
            extra: app.searchdata
        });
        api.closeWin({});
    }




</script>

</html>